/**************************************************************************************
*
*	Copyright (C) 2009 Brent Andrew Chua - See LICENSE.txt for more info.
*		
*	Filename	-	SoundSystem.h
*
*	Description -	A simple FMOD wrapper.
*
*	Comments	-	
*
*	Modification History:
*			Name			   Date					Description
*			CodeSushi	-	12/27/2010		-	Creation of this file
**************************************************************************************/

#ifndef _FMOD_SOUND_SYSTEM_H_
#define _FMOD_SOUND_SYSTEM_H_

#include "../../Pulse Lib/Include/Pulse.h"
#include <fmod.h>
#include <fmod.hpp>
#include <fmod_errors.h>
#include <map>

using namespace Pulse;

class Sound
{
public:

	Sound( void );
	
	Sound( const CHAR *pFilename, Pulse::BOOL bMusic = FALSE );

	~Sound( void );

	Pulse::BOOL LoadSound( const CHAR *pFilename );

	Pulse::BOOL LoadMusic( const CHAR *pFilename );

	void Release( void );

	Pulse::BOOL IsLoaded( void ) { return m_pSound != NULL; }

	const CHAR * GetName( void );

	void SetLoop( Pulse::BOOL bLoop );

	void Play( void );

	void Pause( void );

	void Resume( void );

	void Stop( void );

	Pulse::BOOL IsPlaying( void );

private:


	Sound( Sound & ); // Not allowed
	Sound & operator = ( Sound &rhs ); // Not allowed

	friend class SoundSystem;

	FMOD::Sound * GetFMODSound( void ) { return m_pSound; }

	void RemoveChannel( void ) { m_pChannel = NULL; }

private:

	SoundSystem		*m_pSoundSystem; // Cache our sound system
	String			m_name;
	FMOD::Sound		*m_pSound;
	FMOD::Channel	*m_pChannel;

};

class SoundSystem 
{
public:

	~SoundSystem( void );
	
	static SoundSystem * GetInstance( void );
	static void DeleteInstance( void );

	bool Initialize( INT numChannels = 32 );
	void Shutdown( void );

	void Update( void );

private:

	SoundSystem( void );
	SoundSystem( SoundSystem & );
	SoundSystem & operator = ( SoundSystem &rhs );

private:

	friend Sound;

	// Give access to Sound
	FMOD::Sound * LoadFile( const char *pFilename, Pulse::BOOL bMusic = FALSE );

	FMOD::Channel * PlaySound( Sound *pSound );

private:

	// Data
	typedef std::map< const char *, FMOD::Sound * > FMODSoundMap;

	struct ChannelSoundPair
	{
		ChannelSoundPair( void ) 
			: pChannel( NULL ), pSound( NULL )
		{
		}

		FMOD::Channel *pChannel;
		Sound *pSound;
	};

	static SoundSystem	*m_pInstance;
	FMOD::System		*m_pFMODSystem;
	FMODSoundMap		m_FMODSoundMap;
	ChannelSoundPair	*m_pChannelPairs;
	Pulse::SIZE_T		m_numChannels;

};

#endif /* _FMOD_SOUND_SYSTEM_H_ */